package com.yyl.common.util;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Map;

/**
 *  调用 Restful 接口 util
 */
public class RestUtil {
    private static String domain=null;

    public static String getDomain(){
        if (domain == null) {
            domain=SpringContextUtils.getDomain();
        }
        return domain;
    }

    public static String path=null;

    public static String getPath(){
        if(path==null){
            path=SpringContextUtils.getApplicationContext().getEnvironment().getProperty("servlet.servlet.context-path");
        }
        return path;
    }
    public static String getBaseUrl(){
        return getDomain() +getPath();
    }

    /**
     * RestAPI 调用器
     */
    private final static RestTemplate RT;
    static {
        SimpleClientHttpRequestFactory requestFactory=new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(3000);
        requestFactory.setReadTimeout(3000);
        RT=new RestTemplate(requestFactory);
        // 解决乱码问题
        RT.getMessageConverters().set(1,new StringHttpMessageConverter(StandardCharsets.UTF_8));
    }
    public static RestTemplate getRestTemplate(){
        return RT;
    }
    /**
     * 发送 get 请求
     */
    public static JSONObject get(String url){
        return getNative(url,null,null).getBody();
    }

    /**
     * 发送 get 请求
     */
    public static JSONObject get(String url,JSONObject variables){
        return getNative(url,variables,null).getBody();
    }
    /**
     * 发送get请求
     */
    public static JSONObject get(String url,JSONObject variables,JSONObject params){
        return getNative(url,variables,params).getBody();
    }
    /**
     * 发送 get 请求， 返回原生 ResponseEntity 对象
     */
    public static ResponseEntity<JSONObject> getNative(String url,JSONObject variables,JSONObject params){
        return request(url, HttpMethod.GET,variables,params);
    }

    /**
     * 发送Post 请求
     */
    public static JSONObject post(String url){
        return postNative(url,null,null).getBody();
    }
    /**
     * 发送Post 请求
     */
    public static JSONObject post(String url,JSONObject params){
        return postNative(url,null,params).getBody();
    }

    /**
     * 发送 Post 请求
     */
    public static JSONObject post(String url,JSONObject variables,JSONObject params){
        return postNative(url,variables,params).getBody();
    }

    /**
     * 发送 post 请求，返回 ResponseEntity 对象
     */
    public static ResponseEntity<JSONObject> postNative(String url,JSONObject variables,JSONObject params){
        return request(url,HttpMethod.POST,variables,params);
    }

    /**
     * 发送 put 请求
     */
    public static JSONObject put(String url){
        return putNative(url,null,null).getBody();
    }
    /**
     * 发送put请求
     */
    public static JSONObject put(String url,JSONObject params){
        return putNative(url,null,params).getBody();
    }
/**
 * 发送put 请求
 */
    public static JSONObject put(String url, JSONObject variables, JSONObject params){
        return putNative(url,variables,params).getBody();
    }

    /**
     * 发送 put 请求，返回 原生 ResponseEntity 对象
     */
    public static ResponseEntity<JSONObject> putNative(String url,JSONObject variables,JSONObject params){
        return request(url, HttpMethod.PUT,variables,params);
    }

    /**
     * 发送 delete 请求
     */
    public static JSONObject delete(String url){
        return deleteNative(url,null,null).getBody();
    }

    /**
     * 发送 delete 请求
     */
    public static JSONObject delete(String url,JSONObject variables,JSONObject params){
        return deleteNative(url,variables,params).getBody();
    }
    /**
     *  发送 delete 请求 ，返回原生 ResponseEntity 对象
     */
    public static ResponseEntity<JSONObject> deleteNative(String url,JSONObject variables,JSONObject params){
        return request(url,HttpMethod.DELETE,null,variables,params,JSONObject.class);
    }
    /**
     * 发送请求
     */
    public static ResponseEntity<JSONObject> request(String url,HttpMethod method,JSONObject variables,JSONObject params){
        return request(url,method,getHeaderApplicationJson(),variables,params,JSONObject.class);
    }
    /**
     * 发送请求
     *
     * @param url          请求地址
     * @param method       请求方式
     * @param headers      请求头  可空
     * @param variables    请求url参数 可空
     * @param params       请求body参数 可空
     * @param responseType 返回类型
     * @return ResponseEntity<responseType>
     */
   public static <T> ResponseEntity<T> request(String url, HttpMethod method, HttpHeaders headers,JSONObject variables,JSONObject params,Class<T> responseType){
        if(StringUtils.isEmpty(url)){
            throw new RuntimeException(" url 不能为空");
        }
       if (method == null) {
           throw new RuntimeException("method 不能未空");
       }
       if (headers == null) {
           headers=new HttpHeaders();
       }
       // 请求体
       String body="";
       if (params != null) {
           body= params.toJSONString();
       }
       // 拼接 url 参数
       if(variables!=null){
           url+=("?"+asUrlVariables(variables));
       }
       // 发送请求
       HttpEntity<String> request=new HttpEntity<>(body,headers);
       return RT.exchange(url,method,request,responseType);
   }

    /**
     * 获取JSON请求头
     */
    private static HttpHeaders getHeaderApplicationJson(){
        return getHeeader();
    }
    /**
     * 获取请求头
     */
    private static HttpHeaders getHeeader(){
        HttpHeaders headers=new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE));
        headers.add("Accept",MediaType.APPLICATION_JSON_UTF8_VALUE);
        return headers;
    }
    /**
     * 将 JSONObject 转为 a=1&b=2&c=3...&n-n
     */
    public static String asUrlVariables(JSONObject variables){
        Map<String, Object> source=variables.getInnerMap();
        Iterator<String> it=source.keySet().iterator();
        StringBuilder urlVariables=new StringBuilder();
        while (it.hasNext()){
            String key= it.next();
            String value="";
            Object object=source.get(key);
            if(object!=null){
                if (!StringUtils.isEmpty(object.toString())){
                    value=object.toString();
                }
            }
            urlVariables.append("&").append(key).append("=").append(value);
        }
        // 去掉第一名 &
        return urlVariables.substring(1);
    }




}
